home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / driverss.zip / AR450.ASM < prev    next >
Assembly Source File  |  1991-01-27  |  17KB  |  790 lines

  1. ;History:175,1
  2.  
  3. version    equ    0
  4.  
  5.     include    defs.asm
  6.  
  7. comment \
  8.  
  9. Questions:
  10.  
  11. Why two sets of documentation?
  12.  
  13.     Program to old spec, keeping new in mind...
  14.  
  15. Why does arlan.cfg contain the base address and irq number?
  16.  
  17.     Read the irq first.  If it's nonzero, it's true, otherwise
  18.     use the config file.
  19.  
  20.     just look for telesystems
  21.  
  22. If I give a node id to arlan.cfg, will it override the switches?
  23.  
  24.     Only if it's non-zero.
  25.  
  26. Note from Tom says System Parameters are at 200h
  27.  
  28. Should I read all 512 bytes of arlan.cfg into 100h?
  29.  
  30.     No, only the last 256.
  31.  
  32. Is the configured status byte only present on machines w/ NV RAM?
  33.  
  34. \
  35.  
  36.  
  37. arlan_segment    segment at 0
  38.  
  39.         org    000h
  40. ar_signature    db    ?
  41.  
  42.         org    030h
  43. ar_reset    db    ?
  44.  
  45.         org    031h
  46. ar_diagnostics    db    ?
  47.  
  48.         org    040h
  49. ar_node_id    db    EADDR_LEN dup(?)    ;6 byte node address field.
  50.  
  51.         org    046h
  52. ar_node_bcast    db    EADDR_LEN dup(?)    ;6 byte broadcast address.
  53.  
  54.         org    04ch
  55. ar_type        db    ?        ;1 byte hardware type
  56. ar_type_A450    equ    00h
  57. ar_type_A650    equ    01h
  58. ar_type_A670    equ    0bh
  59. ar_type_A670E    equ    0ch
  60. ar_type_A650E    equ    0dh
  61. ar_type_A440LT    equ    0eh
  62.  
  63.         org    04dh
  64. ar_version    label    word        ;Version number.
  65. ar_version_maj    db    ?
  66. ar_version_min    db    ?
  67.  
  68.         org    080h
  69. ar_interrupt    db    ?        ;not used by LANCPU
  70.  
  71.         org    081h
  72. ar_control_i    db    ?        ;image of the control register.
  73.  
  74.         org    090h
  75. ar_command    db    ?
  76.  
  77. COM_CONF    equ    1
  78. COM_RX_ENABLE    equ    3
  79. COM_RX_ABORT    equ    4
  80. COM_TX_ENABLE    equ    5
  81. COM_TX_ABORT    equ    6
  82. COM_NOP        equ    7
  83. COM_INT        equ    80h
  84.  
  85.         org    0a0h
  86. ar_rx_status    db    ?
  87.  
  88.         org    0a2h
  89. ar_rx_offset    dw    ?        ;start of received datagram
  90.  
  91.         org    0a4h
  92. ar_rx_length    dw    ?        ;length of received datagram
  93.  
  94.         org    0a6h
  95. ar_rx_src    db    EADDR_LEN dup(?)    ;RX source address.
  96.  
  97.         org    0ach
  98. ar_rx_bcast    db    ?        ;<>0 if received frame was bcast.
  99.  
  100.         org    0adh
  101. ar_rx_quality    db    ?        ;indicates quality of received packet.
  102.  
  103.         org    0b0h
  104. ar_tx_status    db    ?
  105.  
  106.         org    0b1h
  107. ar_tx_quality    db    ?
  108.  
  109.         org    100h
  110. ar_sys_params    label    byte
  111.  
  112.         org    108h
  113. ar_irq_level    db    ?        ;IRQ level
  114.  
  115.         org    109h
  116. ar_spreading    db    3 dup(?)    ;Spread spectrum code ID.
  117.  
  118.         org    10ch
  119. ar_NID        dw    ?        ;Radio address of LAN card.
  120.  
  121.         org    11dh
  122. ar_tx_atten    db    ?        ;attenuation of radio transmitter in db.
  123.  
  124.         org    11eh
  125. ar_system_id    dd    ?        ;system ID.
  126.  
  127.         org    128h
  128. ar_MDS        dw    ?        ;Maximum Datagram Size.
  129.  
  130.         org    12ah
  131. ar_MFS        dw    ?        ;Maximum Frame Size.
  132.  
  133.         org    12ch
  134. ar_max_retry    db    ?
  135.  
  136.         org    162h
  137. ar_register    db    ?        ;indicates if card must register w/ router.
  138.  
  139.         org    164h
  140. ar_poll_rate    dw    ?        ;<>0 if power saving is used.
  141.  
  142.         org    166h
  143. ar_refresh_rate    dw    ?        ;tens of msecs between registration
  144.                     ;refreshes.
  145.         org    168h
  146. ar_name        db    16 dup(?)
  147.  
  148.         org    400h
  149. ar_tx_buffer    label    byte
  150.  
  151.         org    0c00h
  152. ar_rx_buffer    label    byte
  153.  
  154.         org    1fffh
  155. ar_control    db    ?
  156. CONTROL_RESET    equ    1
  157. CONTROL_CA    equ    2
  158. CONTROL_IE    equ    4
  159. CONTROL_CLRI    equ    8
  160.  
  161.  
  162. arlan_segment    ends
  163.  
  164. code    segment    word public
  165.     assume    cs:code, ds:code
  166.  
  167.     public    int_no
  168. int_no    db    0,0,0,0            ;must be four bytes long for get_number.
  169.  
  170. base_addr    dw    ?        ;The base address of the board.
  171.  
  172. xmit_bdcast    db    ?
  173.  
  174.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  175. driver_class    db    BLUEBOOK,0    ;from the packet spec
  176. driver_type    db    99        ;from the packet spec
  177. driver_name    db    'ARLAN 450',0    ;name of the driver.
  178. driver_function    db    2
  179. parameter_list    label    byte
  180.     db    1    ;major rev of packet driver
  181.     db    9    ;minor rev of packet driver
  182.     db    14    ;length of parameter list
  183.     db    EADDR_LEN    ;length of MAC-layer address
  184.     dw    GIANT    ;MTU, including MAC headers
  185.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  186.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  187.     dw    0    ;(# of successive xmits) - 1
  188. int_num    dw    0    ;Interrupt # to hook for post-EOI
  189.             ;processing, 0 == none,
  190.  
  191.     public    rcv_modes
  192. rcv_modes    dw    4        ;number of receive modes in our table.
  193.         dw    0,0,0,rcv_mode_3
  194.  
  195.     public    as_send_pkt
  196. ; The Asynchronous Transmit Packet routine.
  197. ; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
  198. ;   interrupts possibly enabled.
  199. ; Exit with nc if ok, or else cy if error, dh set to error number.
  200. ;   es:di and interrupt enable flag preserved on exit.
  201. as_send_pkt:
  202.     ret
  203.  
  204.     public    drop_pkt
  205. ; Drop a packet from the queue.
  206. ; Enter with es:di -> iocb.
  207. drop_pkt:
  208.     assume    ds:nothing
  209.     ret
  210.  
  211.     public    xmit
  212. ; Process a transmit interrupt with the least possible latency to achieve
  213. ;   back-to-back packet transmissions.
  214. ; May only use ax and dx.
  215. xmit:
  216.     assume    ds:nothing
  217.     ret
  218.  
  219.  
  220.     include    timeout.asm
  221.     include    movemem.asm
  222.  
  223.     public    send_pkt
  224. send_pkt:
  225. ;enter with es:di->upcall routine, (0:0) if no upcall is desired.
  226. ;  (only if the high-performance bit is set in driver_function)
  227. ;enter with ds:si -> packet, cx = packet length.
  228. ;if we're a high-performance driver, es:di -> upcall.
  229. ;exit with nc if ok, or else cy if error, dh set to error number.
  230.     assume    ds:nothing
  231.  
  232.     mov    es,base_addr
  233.     assume    es:arlan_segment
  234.  
  235.     cmp    cx,ar_MDS        ;Is this packet too large?
  236.     mov    dh,NO_SPACE
  237.     ja    send_pkt_toobig        ;yes, don't bother sending it.
  238.  
  239.   if 0
  240.     mov    bx,2            ;count the number of times around...
  241. wait_again:
  242.     mov    ax,10            ;don't wait too long...
  243.     call    set_timeout
  244. wait_for_xmit:
  245.     sti
  246.     cmp    ar_tx_status,0        ;is the transmit done?
  247.     jne    xmit_done        ;yes, exit now.
  248.     call    do_timeout
  249.     jne    wait_for_xmit        ;no, wait for it to finish.
  250.     cli
  251.  
  252.     inc    ar_interrupt        ;note that we had to crap out.
  253.  
  254.     mov    ar_command,COM_TX_ABORT
  255.     call    doca
  256.     mov    ar_tx_status,1
  257.   else
  258.     sti
  259. wait_for_xmit:
  260.     cmp    ar_tx_status,0        ;is the transmit done?
  261.     jne    xmit_done        ;yes, exit now.
  262.     jmp    wait_for_xmit        ;no, wait for it to finish.
  263.   endif
  264.     clc                ;pretend we actually sent it.
  265.     ret
  266. send_pkt_toobig:
  267.     stc
  268.     ret
  269. xmit_done:
  270.     cli
  271.  
  272.     mov    di,offset ar_command + 5
  273.  
  274.     mov    xmit_bdcast,0
  275.  
  276. ;check to see if it's an Ethernet broadcast (all ones).
  277.     push    ds
  278.     push    si
  279.     push    cx
  280.     mov    cx,EADDR_LEN
  281. send_pkt_1:
  282.     lodsb
  283.     cmp    al,0ffh
  284.     loope    send_pkt_1
  285.     jne    send_pkt_2        ;not Ethernet broadcast.
  286.  
  287.     inc    xmit_bdcast        ;remember that it was a broadcast.
  288.  
  289.     mov    si,offset ar_node_bcast    ;use our broadcast address.
  290.     mov    ds,base_addr
  291.  
  292.     movsw                ;move the broadcast address over.
  293.     movsw
  294.     movsw
  295.  
  296.     pop    cx
  297.     pop    si
  298.     pop    ds
  299.  
  300.     add    si,EADDR_LEN        ;skip the addresses.
  301.     jmp    short send_pkt_3
  302. send_pkt_2:
  303.     pop    cx
  304.     pop    si
  305.     pop    ds
  306.  
  307.     movsw                ;move the destination address over.
  308.     movsw
  309.     movsw
  310.  
  311. send_pkt_3:
  312.     add    si,EADDR_LEN        ;skip the addresses.
  313.     sub    cx,EADDR_LEN+EADDR_LEN    ;. .
  314.  
  315.     mov    di,offset ar_tx_buffer
  316.     mov    al,xmit_bdcast
  317.     stosb
  318.     push    cx
  319.     call    movemem
  320.     pop    cx
  321.  
  322.     inc    cx            ;include the broadcast byte.
  323.  
  324.     mov    ar_command,COM_TX_ENABLE
  325.     mov    word ptr ar_command[1],offset ar_tx_buffer
  326.     mov    word ptr ar_command[3],cx
  327.  
  328.     mov    ar_tx_status,0        ;let the board fill it in.
  329.  
  330.     call    doca
  331.  
  332.     clc
  333.     ret
  334.  
  335.  
  336.     public    get_address
  337. get_address:
  338. ;get the address of the interface.
  339. ;enter with es:di -> place to get the address, cx = size of address buffer.
  340. ;exit with nc, cx = actual size of address, or cy if buffer not big enough.
  341.     assume    ds:code
  342.     cmp    cx,EADDR_LEN        ; Caller wants a reasonable length?
  343.     jb    get_addr_x        ; No, fail.
  344.     mov    cx,EADDR_LEN        ; Move one ethernet address from our copy
  345.     mov    si,offset ar_node_id    ; Copy from the board.
  346.     push    ds
  347.     mov    ds,base_addr
  348.     rep     movsb
  349.     pop    ds
  350.     mov    cx,EADDR_LEN        ; Tell caller how many bytes we fed him
  351.     clc                ; Carry off says success
  352.     ret
  353. get_addr_x:
  354.     stc                ; Tell caller our addr is too big for him
  355.     ret
  356.  
  357.  
  358.     public    set_address
  359. set_address:
  360. ;enter with ds:si -> Ethernet address, CX = length of address.
  361. ;exit with nc if okay, or cy, dh=error if any errors.
  362.     assume    ds:nothing
  363.     ret
  364.  
  365.  
  366. rcv_mode_3:
  367. ;receive mode 3 is the only one we support, so we don't have to do anything.
  368.     ret
  369.  
  370.  
  371.     public    set_multicast_list
  372. set_multicast_list:
  373. ;enter with ds:si ->list of multicast addresses, cx = number of addresses.
  374. ;return nc if we set all of them, or cy,dh=error if we didn't.
  375.     mov    dh,NO_MULTICAST
  376.     stc
  377.     ret
  378.  
  379.  
  380.     public    terminate
  381. terminate:
  382.     clc
  383.     ret
  384.  
  385.     public    reset_interface
  386. reset_interface:
  387. ;reset the interface.
  388.     assume    ds:code
  389.     ret
  390.  
  391.  
  392. ;called when we want to determine what to do with a received packet.
  393. ;enter with cx = packet length, es:di -> packet type, dl = packet class.
  394.     extrn    recv_find: near
  395.  
  396. ;called after we have copied the packet into the buffer.
  397. ;enter with ds:si ->the packet, cx = length of the packet.
  398.     extrn    recv_copy: near
  399.  
  400.     extrn    count_in_err: near
  401.     extrn    count_out_err: near
  402.  
  403.     public    recv
  404. recv:
  405. ;called from the recv isr.  All registers have been saved, and ds=cs.
  406. ;Upon exit, the interrupt will be acknowledged.
  407.     assume    ds:code, es:arlan_segment
  408.     mov    es,base_addr
  409.  
  410. ;clear the interrupt request.
  411.  
  412.     mov    al,ar_control_i    ;drop the clear interrupt bit.
  413.     and    al,not CONTROL_CLRI
  414.     mov    ar_control,al
  415.     or    al,CONTROL_CLRI        ;raise the clear interrupt bit.
  416.     mov    ar_control,al
  417.  
  418.     cmp    ar_rx_status,0        ;was this our receive interrupt?
  419.     jne    recv_recv
  420.     cmp    ar_tx_status,0        ;was this our transmit interrupt?
  421.     jne    recv_xmit
  422.     jmp    recv_exit
  423. recv_xmit:
  424.     jmp    recv_exit
  425.  
  426. recv_recv:
  427.     mov    di,ar_rx_offset        ;get a pointer to the packet.
  428.     mov    cx,ar_rx_length        ;get the length.
  429.     dec    cx            ;omit the "was broadcast" flag.
  430.     inc    di            ;. .
  431.     add    cx,EADDR_LEN+EADDR_LEN    ;add the two headers in.
  432.     push    es
  433.     push    di
  434.     push    cx
  435.     mov    dl, BLUEBOOK        ;assume bluebook Ethernet.
  436.     call    recv_find
  437.     pop    cx
  438.     pop    si
  439.     pop    ds
  440.     assume    ds:arlan_segment, es:nothing
  441.  
  442.     mov    ax,es            ;is this pointer null?
  443.     or    ax,di
  444.     je    recv_free        ;yes - just free the frame.
  445.  
  446.     push    es
  447.     push    di
  448.     push    cx
  449.     sub    cx,EADDR_LEN+EADDR_LEN
  450.     mov    al,ds:[si-1]        ;get the "was broadcast" flag.
  451.     cmp    al,0            ;was it a broadcast?
  452.     je    recv_us            ;no.
  453.     mov    ax,0ffffh        ;yes, stuff an Ethernet broadcast in.
  454.     stosw
  455.     stosw
  456.     stosw
  457.     jmp    short recv_source
  458. recv_us:
  459.     mov    si,offset ar_node_id
  460.     movsw
  461.     movsw
  462.     movsw
  463. recv_source:
  464.     mov    si,offset ar_rx_src    ;move the source address over.
  465.     movsw
  466.     movsw
  467.     movsw
  468.     mov    si,ar_rx_offset        ;get a pointer to the packet.
  469.     inc    si
  470.     rep    movsb
  471.     pop    cx
  472.     pop    si
  473.     pop    ds
  474.     assume    ds:nothing
  475.  
  476.     call    recv_copy
  477.  
  478. recv_free:
  479.  
  480.     push    cs
  481.     pop    ds
  482.     assume    ds:code
  483.     mov    es,base_addr
  484.     assume    es:arlan_segment
  485.  
  486. enable_receive:
  487.  
  488.     mov    ar_rx_status,0        ;clear the current status.
  489.     mov    ar_command,COM_RX_ENABLE+COM_INT
  490.     mov    ar_command+1,1        ;receive broadcasts.
  491.     call    doca
  492.  
  493.     cmp    ar_rx_status,0        ;is there another packet?
  494.     jne    recv_recv        ;yes, receive it now.
  495.  
  496. recv_exit:
  497.     ret
  498.  
  499.  
  500.     public    recv_exiting
  501. recv_exiting:
  502. ;called from the recv isr after interrupts have been acknowledged.
  503. ;Only ds and ax have been saved.
  504.     assume    ds:nothing
  505.     ret
  506.  
  507. doca:
  508. ;toggle the CA bit in the control register.
  509. ;must be executed with interrupts off to protect ar_control_i.
  510. ;return cy if we had a horrible failure.
  511.     assume    es:arlan_segment
  512.     pushf                ;make up a fake iret stack frame.
  513.     cli
  514.     mov    al,ar_control_i    ;toggle the bit in the image
  515.     xor    al,CONTROL_CA
  516.     mov    ar_control_i,al    ;and store them both.
  517.     mov    ar_control,al
  518.     popf
  519.  
  520.     mov    ax,5            ;wait about 1/7th of a second.
  521.     call    set_timeout
  522. doca_2:
  523.     cmp    ar_command,0        ;wait for the command to finish.
  524.     je    doca_1            ;it did.
  525.     call    do_timeout
  526.     jne    doca_2
  527.     stc
  528.     ret
  529. doca_1:
  530.     clc
  531.     ret
  532.  
  533. ;any code after this will not be kept after initialization.
  534. end_resident    label    byte
  535.  
  536.  
  537.     extrn    error: near
  538.  
  539.     public    usage_msg
  540. usage_msg    db    "usage: ar450 [-n] [-d] [-w] <packet_int_no>",CR,LF,'$'
  541.  
  542.     public    copyright_msg
  543. copyright_msg    db    "Packet driver for an ARLAN 450, version ",'0'+majver,".",'0'+version,CR,LF
  544.         db    "Portions Copyright 1990, Russell Nelson",CR,LF,'$'
  545.  
  546.     extrn    set_recv_isr: near
  547.  
  548. ;enter with si -> argument string, di -> wword to store.
  549. ;if there is no number, don't change the number.
  550.     extrn    get_number: near
  551.  
  552. ;enter with dx -> argument string, di -> wword to print.
  553.     extrn    print_number: near
  554.  
  555.     public    parse_args
  556. parse_args:
  557. ;exit with nc if all went well, cy otherwise.
  558.     clc
  559.     ret
  560.  
  561.  
  562. signature    db    "TELESYSTEM"
  563. signature_len    equ    $-signature
  564.  
  565. no_board_msg    db    "Cannot locate an ARLAN board.",'$'
  566. self_test_msg    db    "ARLAN board self-tests bad.",'$'
  567. bad_mem_msg    db    "The on-card memory tests as bad.",'$'
  568. file_not_found    db    "File not found",'$'
  569. read_trouble    db    "Trouble reading the file",'$'
  570. timeout_msg_xx    db    "x"
  571. timeout_msg_x    db    "x"
  572. timeout_msg    db    "Timed out waiting for the board",'$'
  573. configure_bad    db    "The configure attempt failed",'$'
  574.  
  575. arlan_cfg    db    "arlan.cfg",0
  576. handle        dw    ?
  577.  
  578. int_no_name    db    "Interrupt number ",'$'
  579.  
  580.     public    etopen
  581. etopen:
  582.     assume    ds:code, es:arlan_segment
  583.  
  584. ;look for the arlan card in memory
  585.     mov    dx,0c000h
  586. etopen_1:
  587.     mov    si,offset signature
  588.     mov    es,dx
  589.     mov    di,offset ar_signature
  590.     mov    cx,signature_len
  591.     repe    cmpsb
  592.     je    etopen_2
  593.  
  594.     add    dx,200h
  595.     cmp    dx,0de00h
  596.     jb    etopen_1
  597.     mov    dx,offset no_board_msg
  598.     jmp    error
  599. etopen_2:
  600.     mov    base_addr,dx
  601.  
  602.     mov    ar_control,1        ;reset the board.
  603.  
  604.     mov    ax,base_addr        ;test the memory.
  605.     mov    cx,2000h-3
  606.     call    memory_test
  607.     je    memory_ok
  608.     mov    dx,offset bad_mem_msg
  609.     jmp    error
  610. memory_ok:
  611.  
  612.     xor    di,di            ;zero all the memory.
  613.     mov    cx,2000h-1
  614.     xor    al,al
  615.     rep    stosb
  616.  
  617.     mov    ar_reset,1        ;set the reset flag.
  618.     mov    ar_control,0        ;remove the reset.
  619.  
  620.     mov    ax,36
  621.     call    set_timeout
  622. wait_for_reset:
  623.     cmp    ar_reset,0        ;did it finish resetting yet?
  624.     je    wait_for_reset_1    ;yes, exit.
  625.     call    do_timeout
  626.     jne    wait_for_reset
  627.     mov    dx,offset timeout_msg
  628.     jmp    error
  629. wait_for_reset_1:
  630.  
  631. ;set the reset flag again, so that we can detect if we somehow got reset.
  632.  
  633.     mov    ar_reset,1
  634.  
  635.     cmp    ar_diagnostics,0ffh    ;Did it self-check okay?
  636.     je    self_test_ok
  637.     mov    dx,offset self_test_msg
  638.     jmp    error
  639. self_test_ok:
  640.  
  641.     mov    ar_command,COM_NOP    ;do a NOP.
  642.     call    doca
  643.     jnc    wait_for_first_nop_1
  644.     mov    dx,offset self_test_msg
  645.     jmp    error
  646. wait_for_first_nop_1:
  647.  
  648. ;;; They say to do another with with COM_INT set...
  649.  
  650.     mov    al,ar_irq_level        ;copy the interrupt number out of
  651.     mov    int_no,al        ;  the configuration file.
  652.  
  653.     mov    ax,3d00h        ;open for reading.
  654.     mov    dx,offset arlan_cfg
  655.     int    21h
  656.     jnc    file_found
  657.     mov    dx,offset file_not_found
  658.     jmp    error
  659.  
  660. file_found:
  661.     mov    handle,ax
  662.  
  663.     mov    ax,4200h
  664.     mov    bx,handle
  665.     xor    cx,cx
  666.     mov    dx,100h            ;skip past the first 100h bytes.
  667.     int    21h
  668.  
  669.     mov    ah,3fh            ;read the system parameters.
  670.     mov    bx,handle
  671.     mov    cx,100h
  672.     mov    dx,offset ar_sys_params
  673.     push    ds
  674.     mov    ds,base_addr
  675.     int    21h
  676.     pop    ds
  677.     jnc    no_trouble
  678.     mov    dx,offset read_trouble
  679.     jmp    error
  680.  
  681. no_trouble:
  682.  
  683.     mov    ah,3eh            ;close the file.
  684.     mov    bx,handle
  685.     int    21h
  686.  
  687.     cmp    int_no,0        ;Does the board know its interrupt
  688.     jne    set_int_no        ;  number?  go if it does.
  689.     mov    al,ar_irq_level        ;No, so use the one
  690.     mov    int_no,al        ;  in the configuration file.
  691. set_int_no:
  692.  
  693. ; do the configure.
  694.  
  695.     mov    ar_command,COM_CONF
  696.     call    doca
  697.     jnc    wait_for_configure_1    ;it did.
  698.     mov    dx,offset timeout_msg_x
  699.     jmp    error
  700. wait_for_configure_1:
  701.  
  702.     cmp    ar_diagnostics,0ffh    ;did the configure succeed?
  703.     je    configure_ok
  704.     mov    dx,offset configure_bad
  705.     jmp    error
  706. configure_ok:
  707.  
  708. ;wait a short while for the AR450.  For the AR440, wait up to 15 seconds.
  709.  
  710.     mov    ax,36
  711.     call    set_timeout
  712. wait_for_address:
  713.     mov    cx,EADDR_LEN        ;see if our address is still zeroes.
  714.     mov    si,offset ar_node_id
  715.     xor    al,al
  716. wait_for_address_2:
  717.     or    al,es:[si]
  718.     inc    si
  719.     loop    wait_for_address_2
  720.     or    al,al            ;do we have an address yet?
  721.     jne    wait_for_address_1    ;yes.
  722.     call    do_timeout
  723.     jne    wait_for_address
  724.     mov    dx,offset timeout_msg_xx
  725.     jmp    error
  726. wait_for_address_1:
  727.  
  728. ;say that the max we'll send is an Ethernet GIANT packet, less the two
  729. ;  Ethernet addresses that we don't include in the datagram, plus the one
  730. ;  broadcast byte that we *do* include.
  731.  
  732.     mov    ax,GIANT - EADDR_LEN*2 + 1
  733.     mov    ax,1023
  734.     mov    ar_MDS,ax
  735.     mov    ar_MFS,ax
  736.  
  737. ; reduce the number of retries
  738.  
  739.     mov    ar_max_retry,16
  740.  
  741. ;enable reception
  742.  
  743.     call    enable_receive
  744.  
  745. ;mark transmission as done
  746.  
  747.     mov    ar_tx_status,1
  748.  
  749. ;enable our interrupts.
  750.  
  751.     mov    al,ar_control_i
  752.     or    al,CONTROL_IE or CONTROL_CLRI
  753.     mov    ar_control_i,al
  754.     mov    ar_control,al
  755.  
  756. ; Now hook in our interrupt
  757.  
  758.     call    set_recv_isr
  759.  
  760.     sti
  761.  
  762.     mov    al, int_no        ; Get board's interrupt vector
  763.     add    al, 8
  764.     cmp    al, 8+8            ; Is it a slave 8259 interrupt?
  765.     jb    set_int_num        ; No.
  766.     add    al, 70h - 8 - 8        ; Map it to the real interrupt.
  767. set_int_num:
  768.     xor    ah, ah            ; Clear high byte
  769.     mov    int_num, ax        ; Set parameter_list int num.
  770.  
  771.     mov    dx,offset end_resident
  772.     clc
  773.     ret
  774.  
  775.  
  776.     public    print_parameters
  777. print_parameters:
  778. ;echo our command-line parameters
  779.     mov    dx,offset int_no_name
  780.     mov    di,offset int_no
  781.     call    print_number
  782.  
  783.     ret
  784.  
  785.     include    memtest.asm
  786.  
  787. code    ends
  788.  
  789.     end
  790.